/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Builder;

import DAO.DAOAccess;
import DAO.DAOHelper;
import DAO.InformationFilter.CategoryDAO;
import DAO.InformationFilter.CategoryPageDAO;
import DAO.InformationFilter.InterestingDAO;
import Info.InterestingInfo;
import DAO.InformationFilter.PeriodClickDAO;
import DAO.InformationFilter.PrdDAO;
import DAO.InformationFilter.UsrCategoryClickDAO;
import Info.UserCategoryClickInfo;
import DAO.InformationFilter.UsrClickDAO;
import DAO.InformationFilter.UserDAO;
import Info.CategoryPageInfo;
import Info.PeriodInfo;
import Info.UserInfo;
import MySqlAccess.DataAcessHelper;
import gnu.trove.TIntIntHashMap;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;

/**
 *
 * @author tran tuan tai
 */
public class ModelBuilder
{
    List<UserInfo> m_allUser;
    int G = 10;
    private class PeriodComparator implements Comparator<PeriodInfo>
    {

        public int compare(PeriodInfo o1, PeriodInfo o2) {
            return o1.GetBegin().compareTo(o2.GetBegin());
        }
    }

    public void BuildInteresting(Timestamp currTime)
    {
        /////////  TABLE WRITE  /////////////////////////////////
        PrdDAO periodDAO = PrdDAO.GetInstance();
        List<PeriodInfo> allPeriod = periodDAO.GetAllPeriod();
        Collections.sort(allPeriod, new PeriodComparator());
        if (allPeriod.isEmpty()) return;

        UserDAO userDAO = new UserDAO();
        List<UserInfo> allUser = userDAO.GetAll();
        
        CategoryDAO categoryDAO = new CategoryDAO();
        List<Integer> allCategory = categoryDAO.GetAllID();

        InterestingDAO interestingDAO = new InterestingDAO();
        InterestingDAO.DoEmpty();
        //-----------------------------------------------------------

        //-----------------       TABLE READ         -------------------------
        CategoryPageDAO categoryPageDAO = new CategoryPageDAO();
        UsrCategoryClickDAO userCategoryClickDAO = new UsrCategoryClickDAO();
        UsrClickDAO userClickDAO = new UsrClickDAO();
        //--------------------------------------------------------

        TIntIntHashMap uPeriodClick = new TIntIntHashMap();
        int nPeriod = allPeriod.size();
        for (UserInfo user : allUser)
        {
            for (PeriodInfo period : allPeriod)
            {
                uPeriodClick.put(period.GetID(), userClickDAO.GetNClickByUserPeriod(period, user));
            }

            double interestingAllPast = 0.0;
            for (Integer categoryID : allCategory)
            {
                /////// first period
                PeriodInfo currPeriod = allPeriod.get(0);

                Double perCategoryClick = userCategoryClickDAO.GetProb(user, categoryID, currPeriod);
                Double priorPage = categoryPageDAO.GetProb(currPeriod, categoryID);

                InterestingInfo interInfo = new InterestingInfo();
                interInfo.Category = categoryID;                
                interInfo.User = user.id;
                interInfo.Period = currPeriod.GetID();
                if (user.registeredDate.after(currPeriod.GetBegin()))
                {
                    interInfo.InterestingScore = perCategoryClick;

                    if (priorPage != 0)
                    {
                        interestingAllPast += uPeriodClick.get(currPeriod.GetID())*perCategoryClick/priorPage;
                    }
                }
                else
                {
                    interInfo.InterestingScore = 0;
                }
                interestingDAO.Insert(interInfo);


                for (int idxPeriod = 1; idxPeriod < nPeriod; idxPeriod++)
                {
                    currPeriod = allPeriod.get(idxPeriod);

                    perCategoryClick = userCategoryClickDAO.GetProb(user, categoryID, currPeriod);
                    priorPage = categoryPageDAO.GetProb(currPeriod, categoryID);

                    interInfo = new InterestingInfo();
                    interInfo.Category = categoryID;
                    interInfo.User = user.id;
                    interInfo.Period = currPeriod.GetID();
                    if (user.registeredDate.after(currPeriod.GetBegin()))
                    {
                        interInfo.InterestingScore = priorPage*(interestingAllPast + G)/(uPeriodClick.get(currPeriod.GetID()) + G);
                        if (priorPage != 0)
                        {
                            interestingAllPast += uPeriodClick.get(currPeriod.GetID())*perCategoryClick/priorPage;
                        }
                    }
                    else
                    {
                        interInfo.InterestingScore = 0;
                    }
                    interestingDAO.Insert(interInfo);
                }
            }
        }

    }

    public void Build(Timestamp currTime)
    {
        PrdBuilder periodBuilder = new PrdBuilder();
        periodBuilder.Build(new Timestamp(111, 5, 1, 0, 0, 0, 0));

       PageBuilder pageBuilder = new PageBuilder();
       pageBuilder.Build();

        UsrBuilder userBuilder = new UsrBuilder();
        userBuilder.Builder();      

//        CategoryBuilder categoryBuilder = new CategoryBuilder();
//        categoryBuilder.Build();
//
//        UsrCategoryClickBuilder userCategoryBuilder = new UsrCategoryClickBuilder();
//        userCategoryBuilder.Build();
//
//        CategoryPage_PeriodBuilder categoryPagePeriodBuilder = new CategoryPage_PeriodBuilder();
//        categoryPagePeriodBuilder.Build();
//
//        BuildInteresting(currTime);
    }

    public static void main(String[] argvs)
    {
//        DAOAccess.SetDatabaseName(argvs[0]);
//        DAOAccess.SetPass(argvs[1]);
//        DAOAccess.SetServer(argvs[2]);
//        DAOAccess.SetUser(argvs[3]);
//        DAOAccess.CreateConnection();
//
//        DataAcessHelper.SetDatabaseName(argvs[0]);
//        DataAcessHelper.SetPass(argvs[1]);
//        DataAcessHelper.SetServer(argvs[2]);
//        DataAcessHelper.SetUser(argvs[3]);
//        DataAcessHelper.CreateConnection();
//
//        DAOHelper.SetDatabaseName(argvs[0]);
//        DAOHelper.SetPass(argvs[1]);
//        DAOHelper.SetServer(argvs[2]);
//        DAOHelper.SetUser(argvs[3]);
//        DataAcessHelper.CreateConnection();

        ModelBuilder builder = new ModelBuilder();
        builder.Build(new Timestamp(Calendar.getInstance().getTime().getTime()));
    }
}
